package com.smart.community.payment.dto;

import com.smart.community.commons.base.BaseDTO;
import com.smart.community.commons.enums.SystemStatusEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 支付数据传输对象
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @since 2025-06-26
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class PaymentDTO extends BaseDTO {

    /**
     * 用户ID
     */
    @NotNull(message = "用户ID不能为空")
    private Long userId;

    /**
     * 社区ID
     */
    @NotNull(message = "社区ID不能为空")
    private Long communityId;

    /**
     * 支付订单号
     */
    @Size(max = 64, message = "支付订单号长度不能超过64个字符")
    private String orderNo;

    /**
     * 支付金额
     */
    @NotNull(message = "支付金额不能为空")
    @DecimalMin(value = "0.01", message = "支付金额必须大于0")
    @Digits(integer = 10, fraction = 2, message = "支付金额格式不正确")
    private BigDecimal amount;

    /**
     * 支付方式：1-微信支付，2-支付宝，3-银行卡，4-现金
     */
    @NotNull(message = "支付方式不能为空")
    @Min(value = 1, message = "支付方式值无效")
    @Max(value = 4, message = "支付方式值无效")
    private Integer paymentMethod;

    /**
     * 支付状态：0-待支付，1-支付中，2-支付成功，3-支付失败，4-已退款
     */
    private Integer paymentStatus = SystemStatusEnum.DISABLED.getCode();

    /**
     * 业务类型：1-物业费，2-停车费，3-水电费，4-其他
     */
    @NotNull(message = "业务类型不能为空")
    @Min(value = 1, message = "业务类型值无效")
    @Max(value = 4, message = "业务类型值无效")
    private Integer businessType;

    /**
     * 业务订单ID
     */
    private Long businessOrderId;

    /**
     * 支付描述
     */
    @Size(max = 500, message = "支付描述长度不能超过500个字符")
    private String description;

    /**
     * 支付时间
     */
    private LocalDateTime paymentTime;

    /**
     * 支付渠道编码
     */
    @Size(max = 32, message = "支付渠道编码长度不能超过32个字符")
    private String channelCode;

    /**
     * 第三方支付订单号
     */
    @Size(max = 64, message = "第三方支付订单号长度不能超过64个字符")
    private String thirdPartyOrderNo;

    /**
     * 退款金额
     */
    @DecimalMin(value = "0.00", message = "退款金额不能小于0")
    @Digits(integer = 10, fraction = 2, message = "退款金额格式不正确")
    private BigDecimal refundAmount;

    /**
     * 退款原因
     */
    @Size(max = 500, message = "退款原因长度不能超过500个字符")
    private String refundReason;

    /**
     * 退款时间
     */
    private LocalDateTime refundTime;

    /**
     * 验证支付参数
     * 
     * @return 是否有效
     */
    public boolean validatePayment() {
        return userId != null && communityId != null 
            && amount != null && amount.compareTo(BigDecimal.ZERO) > 0
            && paymentMethod != null && paymentMethod >= 1 && paymentMethod <= 4
            && businessType != null && businessType >= 1 && businessType <= 4;
    }

    /**
     * 验证退款参数
     * 
     * @return 是否有效
     */
    public boolean validateRefund() {
        return refundAmount != null && refundAmount.compareTo(BigDecimal.ZERO) > 0
            && refundReason != null && !refundReason.trim().isEmpty();
    }

    /**
     * 检查是否已退款
     * 
     * @return 是否已退款
     */
    public boolean isRefunded() {
        return paymentStatus != null && paymentStatus.equals(SystemStatusEnum.DELETED.getCode());
    }

    /**
     * 检查是否可以退款
     * 
     * @return 是否可以退款
     */
    public boolean canRefund() {
        return paymentStatus != null && paymentStatus.equals(SystemStatusEnum.ENABLED.getCode()); // 只有支付成功才能退款
    }

    /**
     * 生成支付订单号
     * 
     * @return 订单号
     */
    public String generateOrderNo() {
        if (orderNo != null && !orderNo.trim().isEmpty()) {
            return orderNo;
        }
        // 生成订单号：时间戳 + 用户ID + 随机数
        return "PAY" + System.currentTimeMillis() + userId + (int)(Math.random() * 1000);
    }

    /**
     * 获取支付方式名称
     * 
     * @return 支付方式名称
     */
    public String getPaymentMethodName() {
        if (paymentMethod == null) return "未知";
        switch (paymentMethod) {
            case 1: return "微信支付";
            case 2: return "支付宝";
            case 3: return "银行卡";
            case 4: return "现金";
            default: return "未知";
        }
    }

    /**
     * 获取业务类型名称
     * 
     * @return 业务类型名称
     */
    public String getBusinessTypeName() {
        if (businessType == null) return "未知";
        switch (businessType) {
            case 1: return "物业费";
            case 2: return "停车费";
            case 3: return "水电费";
            case 4: return "其他";
            default: return "未知";
        }
    }

    /**
     * 获取支付状态名称
     * 
     * @return 支付状态名称
     */
    public String getPaymentStatusName() {
        return SystemStatusEnum.getByCode(paymentStatus).getDescription();
    }
}
